home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / devel / lisp / akcl_lin.z / akcl_lin / c / unixfsys.c < prev   
Encoding:
C/C++ Source or Header  |  1993-03-08  |  13.2 KB  |  685 lines

  1. /*
  2. (c) Copyright Taiichi Yuasa and Masami Hagiya, 1984.  All rights reserved.
  3. Copying of this file is authorized to users who have executed the true and
  4. proper "License Agreement for Kyoto Common LISP" with SIGLISP.
  5. */
  6.  
  7. #define IN_UNIXFSYS
  8. #include "include.h"
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #include <pwd.h>
  12.  
  13.  
  14. #define    MAXPATHLEN    1024
  15.  
  16. #ifdef linux
  17. #undef ATT
  18. #define BSD
  19. #endif
  20.  
  21. #ifdef NEED_GETWD
  22. #include <sys/dir.h>
  23.  
  24.  
  25. #ifndef GETCWD
  26. char dotdot[3*16+2] = "../../../../../../../../../../../../../../../../.";
  27. #include <mnttab.h>
  28. static char *getwd_buf;
  29. static int getwd_bufp;
  30.  
  31. char *
  32. getwd(buffer)
  33. char *buffer;
  34. {
  35.     getwd_buf = buffer;
  36.     getwd1(0);
  37.     if (getwd_bufp == 0)
  38.         getwd_buf[getwd_bufp++] = '/';
  39.     getwd_buf[getwd_bufp] = '\0';
  40.     return(getwd_buf);
  41. }
  42.  
  43. getwd1(n)
  44. int n;
  45. {
  46.     struct stat st, dev_st;
  47.     struct direct dir;
  48.     ino_t ino;
  49.     struct mnttab mnt;
  50.     FILE *fp;
  51.     register int i;
  52.     char buf[BUFSIZ];
  53.     static char dev_name[64];
  54.  
  55.     if (stat(dotdot+(16-n)*3, &st) < 0)
  56.         FEerror("Can't get the current working directory.", 0);
  57.     ino = st.st_ino;
  58.     if (ino == 2)
  59.         goto ROOT;
  60.     getwd1(n+1);
  61.     fp = fopen(dotdot+(16-n-1)*3, "r");
  62.     if (fp == NULL)
  63.         FEerror("Can't get the current working directory.", 0);
  64.     setbuf(fp, buf);
  65.     fread(&dir, sizeof(struct direct), 1, fp);
  66.     fread(&dir, sizeof(struct direct), 1, fp);
  67.     for (;;) {
  68.         if (fread(&dir, sizeof(struct direct), 1, fp) <= 0)
  69.             break;
  70.         if (dir.d_ino == ino)
  71.             goto FOUND;
  72.     }
  73.     fclose(fp);
  74.     FEerror("Can't get the current working directory.", 0);
  75.  
  76. FOUND:
  77.     fclose(fp);
  78.     getwd_buf[getwd_bufp++] = '/';
  79.     for (i = 0;  i < DIRSIZ && dir.d_name[i] != '\0';  i++)
  80.         getwd_buf[getwd_bufp++] = dir.d_name[i];
  81.     return;
  82.  
  83. ROOT:
  84.     fp = fopen("/etc/mnttab", "r");
  85.     if (fp == NULL)
  86.         FEerror("Can't get the current working directory.", 0);
  87.     setbuf(fp, buf);
  88.     for (;;) {
  89.         if (fread(&mnt, sizeof(struct mnttab), 1, fp) <= 0)
  90.             break;
  91.         if (mnt.mt_dev[0] != '/') {
  92.             strcpy(dev_name, "/dev/dsk/");
  93.             strcat(dev_name, mnt.mt_dev);
  94.             stat(dev_name, &dev_st);
  95.         } else
  96.             stat(mnt.mt_dev, &dev_st);
  97.         if (dev_st.st_rdev == st.st_dev)
  98.             goto DEV_FOUND;
  99.     }
  100.     fclose(fp);
  101.     getwd_bufp = 0;
  102.     return;
  103.  
  104. DEV_FOUND:
  105.     fclose(fp);
  106.     getwd_bufp = 0;
  107.     for (i = 0;  mnt.mt_filsys[i] != '\0';  i++)
  108.         getwd_buf[i] = mnt.mt_filsys[i];
  109.     /* BUG FIX by Grant J. Munsey */
  110.     if (i == 1 && *getwd_buf == '/')
  111.         i = 0;    /* don't add an empty directory name */
  112.     /* END OF BUG FIX */
  113.     getwd_bufp = i;
  114. }
  115. #endif   /* not GETCWD */
  116. #endif
  117.  
  118. #ifdef GETCWD
  119. char *
  120. getwd(buffer)
  121. char *buffer;
  122. {
  123.     char *getcwd();
  124.  
  125.     return(getcwd(buffer, MAXPATHLEN));
  126. }
  127. #endif
  128.  
  129. #ifdef DGUX
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151.  
  152.  
  153.  
  154.  
  155.  
  156.  
  157.  
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181. #endif
  182.  
  183.  
  184. coerce_to_filename(pathname, p)
  185. object pathname;
  186. char *p;
  187. {
  188.   int n;
  189.   object namestring;
  190.   namestring = coerce_to_namestring(pathname);
  191.   if(namestring->st.st_self[0]=='~')
  192.     {char name[20];
  193.      int j;
  194.      object ans;
  195.      char *q = namestring->st.st_self;
  196.      extern struct passwd *getpwuid();
  197.      extern struct passwd *getpwnam();
  198.        
  199.      char filename[MAXPATHLEN];
  200.      struct passwd *pwent;
  201.      int m;
  202.      q=namestring->st.st_self;
  203.      for (n=0; n< namestring->st.st_fillp; n++)
  204.        if (q[n]=='/') break;
  205.      bcopy(q+1,name,n-1);
  206.      name[n-1]= 0;
  207.      pwent = (n==1 ? getpwuid(getuid()) : getpwnam(name));
  208.      if (pwent==0 || ((m = strlen(pwent->pw_dir))
  209.              && (m + namestring->st.st_fillp -n) >= MAXPATHLEN -16))
  210.        {FEerror("Can't expand pathname ~a", 1,namestring);}
  211.      bcopy(pwent->pw_dir,p,m);
  212.      bcopy(namestring->st.st_self+n,p+m,namestring->st.st_fillp-n);
  213.      p[m+namestring->st.st_fillp-n]=0;}
  214.   else
  215.     {if (namestring->st.st_fillp >= MAXPATHLEN - 16) {
  216.       vs_push(namestring);
  217.       FEerror("Too long filename: ~S.", 1, namestring);}
  218.      bcopy(namestring->st.st_self,p,namestring->st.st_fillp);
  219.      p[namestring->st.st_fillp]=0;}
  220. }
  221.  
  222. object
  223. truename(pathname)
  224. object pathname;
  225. {
  226.     register char *p, *q;
  227.     char filename[MAXPATHLEN];
  228.     char truefilename[MAXPATHLEN];
  229.     char current_directory[MAXPATHLEN];
  230.     char directory[MAXPATHLEN];
  231.     char *getwd();
  232.  
  233.     coerce_to_filename(pathname, filename);
  234.     for (p = filename, q = 0;  *p != '\0';  p++)
  235.         if (*p == '/')
  236.             q = p;
  237.     if (q == filename) {
  238.         q++;
  239.         getwd(current_directory);
  240.         p = "/";
  241.     } else if (q == 0) {
  242.         q = filename;
  243.         p = getwd(current_directory);
  244.     } else {
  245.         *q++ = '\0';
  246.         getwd(current_directory);
  247.         if (chdir(filename) < 0)
  248.             FEerror("Cannot get the truename of ~S.", 1, pathname);
  249.         p = getwd(directory);
  250.     }
  251.     if (p[0] == '/' && p[1] == '\0') {
  252.         if (strcmp(q, "..") == 0)
  253.             strcpy(truefilename, "/.");
  254.         else
  255.             sprintf(truefilename, "/%s", q);
  256.     } else if (strcmp(q, ".") == 0)
  257.         strcpy(truefilename, p);
  258.     else if (strcmp(q, "..") == 0) {
  259.         for (q = p + strlen(p);  *--q != '/';) ;
  260.         if (p == q)
  261.             strcpy(truefilename, "/.");
  262.         else {
  263.             *q = '\0';
  264.             strcpy(truefilename, p);
  265.             *q = '/';
  266.         }
  267.     } else
  268.         sprintf(truefilename, "%s/%s", p, q);
  269.     chdir(current_directory);
  270.     vs_push(make_simple_string(truefilename));
  271.     pathname = coerce_to_pathname(vs_head);
  272.     vs_pop;
  273.     return(pathname);
  274. }
  275.  
  276. bool
  277. file_exists(file)
  278. object file;
  279. {
  280.     char filename[MAXPATHLEN];
  281.     struct stat filestatus;
  282.  
  283.     coerce_to_filename(file, filename);
  284.     if (stat(filename, &filestatus) >= 0)
  285.       {
  286. #ifdef AIX
  287.         /* if /tmp/foo is not a directory /tmp/foo/ should not exist */
  288.         if (filename[strlen(filename)-1] == '/' &&
  289.         !( filestatus.st_mode & S_IFDIR))
  290.         return(FALSE);
  291. #endif        
  292.  
  293.         return TRUE;
  294.       }
  295.     
  296.     else
  297.         return(FALSE);
  298. }
  299.  
  300. FILE *
  301. backup_fopen(filename, option)
  302. char *filename,*option;
  303. {
  304.     char backupfilename[MAXPATHLEN];
  305.     char command[MAXPATHLEN * 2];
  306.  
  307.     strcat(strcpy(backupfilename, filename), ".BAK");
  308.     sprintf(command, "mv %s %s", filename, backupfilename);
  309.     system(command);
  310.     return(fopen(filename, option));
  311. }
  312.  
  313. int
  314. file_len(fp)
  315. FILE *fp;
  316. {
  317.     struct stat filestatus;
  318.  
  319.     fstat(fileno(fp), &filestatus);
  320.     return(filestatus.st_size);
  321. }
  322.  
  323. Ltruename()
  324. {
  325.     check_arg(1);
  326.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  327.     vs_base[0] = truename(vs_base[0]);
  328. }
  329.  
  330. Lrename_file()
  331. {
  332.     char filename[MAXPATHLEN];
  333.     char newfilename[MAXPATHLEN];
  334.     char command[MAXPATHLEN * 2];
  335.  
  336.     check_arg(2);
  337.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  338.     check_type_or_Pathname_string_symbol(&vs_base[1]);
  339.     coerce_to_filename(vs_base[0], filename);
  340.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  341.     vs_base[1] = coerce_to_pathname(vs_base[1]);
  342.     vs_base[1] = merge_pathnames(vs_base[1], vs_base[0], Cnil);
  343.     coerce_to_filename(vs_base[1], newfilename);
  344. #ifdef BSD
  345.     if (rename(filename, newfilename) < 0)
  346.         FEerror("Cannot rename the file ~S to ~S.",
  347.             2, vs_base[0], vs_base[1]);
  348. #else
  349.     sprintf(command, "mv %s %s", filename, newfilename);
  350.     system(command);
  351. #endif
  352.     vs_push(vs_base[1]);
  353.     vs_push(truename(vs_base[0]));
  354.     vs_push(truename(vs_base[1]));
  355.     vs_base += 2;
  356. }
  357.  
  358. Ldelete_file()
  359. {
  360.     char filename[MAXPATHLEN];
  361.  
  362.     check_arg(1);
  363.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  364.     coerce_to_filename(vs_base[0], filename);
  365.     if (unlink(filename) < 0)
  366.         FEerror("Cannot delete the file ~S.", 1, vs_base[0]);
  367.     vs_base[0] = Ct;
  368. }
  369.  
  370. Lprobe_file()
  371. {
  372.     check_arg(1);
  373.  
  374.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  375.     if (file_exists(vs_base[0]))
  376.         vs_base[0] = truename(vs_base[0]);
  377.     else
  378.         vs_base[0] = Cnil;
  379. }
  380.  
  381. Lfile_write_date()
  382. {
  383.     char filename[MAXPATHLEN];
  384.     struct stat filestatus;
  385.  
  386.     check_arg(1);
  387.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  388.     coerce_to_filename(vs_base[0], filename);
  389.     if (stat(filename, &filestatus) < 0) { vs_base[0] = Cnil; return;}
  390.     vs_base[0] = unix_time_to_universal_time(filestatus.st_mtime);
  391. }
  392.  
  393. Lfile_author()
  394. {
  395.     char filename[MAXPATHLEN];
  396.     struct stat filestatus;
  397.     struct passwd *pwent;
  398.     extern struct passwd *getpwuid();
  399.  
  400.     check_arg(1);
  401.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  402.     coerce_to_filename(vs_base[0], filename);
  403.     if (stat(filename, &filestatus) < 0) { vs_base[0] = Cnil; return;}
  404.     pwent = getpwuid(filestatus.st_uid);
  405.     vs_base[0] = make_simple_string(pwent->pw_name);
  406. }
  407.  
  408. Luser_homedir_pathname()
  409. {
  410.     struct passwd *pwent;
  411.     char filename[MAXPATHLEN];
  412.     register int i;
  413.     extern struct passwd *getpwuid();
  414.  
  415.     if (vs_top - vs_base > 1)
  416.         too_many_arguments();
  417.     pwent = getpwuid(getuid());
  418.     strcpy(filename, pwent->pw_dir);
  419.     i = strlen(filename);
  420.     if (filename[i-1] != '/') {
  421.         filename[i++] = '/';
  422.         filename[i] = '\0';
  423.     }
  424.     vs_base[0] = make_simple_string(filename);
  425.     vs_top = vs_base+1;
  426.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  427. }
  428.  
  429.  
  430. #ifdef BSD
  431. Ldirectory()
  432. {
  433.     char filename[MAXPATHLEN];
  434.     char command[MAXPATHLEN * 2];
  435.     FILE *fp;
  436.     register i, c;
  437.     object *top = vs_top;
  438.     char iobuffer[BUFSIZ];
  439.     extern FILE *popen();
  440.  
  441.     check_arg(1);
  442.  
  443.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  444.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  445.     if (vs_base[0]->pn.pn_name==Cnil && vs_base[0]->pn.pn_type==Cnil) {
  446.         coerce_to_filename(vs_base[0], filename);
  447.         strcat(filename, "*");
  448.     } else if (vs_base[0]->pn.pn_name==Cnil) {
  449.         vs_base[0]->pn.pn_name = Kwild;
  450.         coerce_to_filename(vs_base[0], filename);
  451.         vs_base[0]->pn.pn_name = Cnil;
  452.     } else if (vs_base[0]->pn.pn_type==Cnil) {
  453.         coerce_to_filename(vs_base[0], filename);
  454.         strcat(filename, "*");
  455.     } else
  456.         coerce_to_filename(vs_base[0], filename);
  457.     sprintf(command, "ls -d %s 2> /dev/null", filename);
  458.     fp = popen(command, "r");
  459.     setbuf(fp, iobuffer);
  460.     for (;;) {
  461.         for (i = 0;  c = getc(fp);  i++)
  462.             if (c <= 0)
  463.                 goto L;
  464.             else if (c == '\n')
  465.                 break;
  466.             else
  467.                 filename[i] = c;
  468.         filename[i] = '\0';
  469.         vs_push(make_simple_string(filename));
  470.         vs_head = truename(vs_head);
  471.     }
  472. L:
  473.     pclose(fp);
  474.     vs_push(Cnil);
  475.     while (vs_top > top + 1)
  476.         stack_cons();
  477.     vs_base = top;
  478. }
  479. #endif
  480.  
  481.  
  482. #ifdef ATT
  483. Ldirectory()
  484. {
  485.     object name, type;
  486.     char filename[MAXPATHLEN];
  487.     FILE *fp;
  488.     object *top = vs_top;
  489.     char iobuffer[BUFSIZ];
  490.     struct direct dir;
  491.     int i;
  492.  
  493.     check_arg(1);
  494.  
  495.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  496.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  497.     vs_push(vs_base[0]->pn.pn_name);
  498.     vs_push(vs_base[0]->pn.pn_type);
  499.     vs_base[0]->pn.pn_name = Cnil;
  500.     vs_base[0]->pn.pn_type = Cnil;
  501.     coerce_to_filename(vs_base[0], filename);
  502.     type = vs_base[0]->pn.pn_type = vs_pop;
  503.     name = vs_base[0]->pn.pn_name = vs_pop;
  504.     i = strlen(filename);
  505.     if (i > 1 && filename[i-1] == '/')
  506.         filename[i-1] = '\0';
  507.     if (i == 0)
  508.         strcpy(filename, ".");
  509.     fp = fopen(filename, "r");
  510.     if (fp == NULL) {
  511.         vs_push(make_simple_string(filename));
  512.         FEerror("Can't open the directory ~S.", 1, vs_head);
  513.     }
  514.     setbuf(fp, iobuffer);
  515.     fread(&dir, sizeof(struct direct), 1, fp);
  516.     fread(&dir, sizeof(struct direct), 1, fp);
  517.     filename[DIRSIZ] = '\0';
  518.     for (;;) {
  519.         if (fread(&dir, sizeof(struct direct), 1, fp) <=0)
  520.             break;
  521.         if (dir.d_ino == 0)
  522.             continue;
  523.         strncpy(filename, dir.d_name, DIRSIZ);
  524.         vs_push(make_simple_string(filename));
  525.         vs_head = coerce_to_pathname(vs_head);
  526.         if ((name == Cnil || name == Kwild ||
  527.              equal(name, vs_head->pn.pn_name)) &&
  528.             (type == Cnil || type == Kwild ||
  529.              equal(type, vs_head->pn.pn_type))) {
  530.             vs_head->pn.pn_directory
  531.             = vs_base[0]->pn.pn_directory;
  532.             vs_head = truename(vs_head);
  533.         } else
  534.             vs_pop;
  535.     }
  536.     fclose(fp);
  537.     vs_push(Cnil);
  538.     while (vs_top > top + 1)
  539.         stack_cons();
  540.     vs_base = top;
  541. }
  542. #endif
  543.  
  544.  
  545. #ifdef E15
  546. #include <sys/dir.h>
  547. Ldirectory()
  548. {
  549.     object name, type;
  550.     char filename[MAXPATHLEN];
  551.     FILE *fp;
  552.     object *top = vs_top;
  553.     char iobuffer[BUFSIZ];
  554.     struct direct dir;
  555.     int i;
  556.  
  557.     check_arg(1);
  558.  
  559.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  560.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  561.     vs_push(vs_base[0]->pn.pn_name);
  562.     vs_push(vs_base[0]->pn.pn_type);
  563.     vs_base[0]->pn.pn_name = Cnil;
  564.     vs_base[0]->pn.pn_type = Cnil;
  565.     coerce_to_filename(vs_base[0], filename);
  566.     type = vs_base[0]->pn.pn_type = vs_pop;
  567.     name = vs_base[0]->pn.pn_name = vs_pop;
  568.     i = strlen(filename);
  569.     if (i > 1 && filename[i-1] == '/')
  570.         filename[i-1] = '\0';
  571.     if (i == 0)
  572.         strcpy(filename, ".");
  573.     fp = fopen(filename, "r");
  574.     if (fp == NULL) {
  575.         vs_push(make_simple_string(filename));
  576.         FEerror("Can't open the directory ~S.", 1, vs_head);
  577.     }
  578.     setbuf(fp, iobuffer);
  579.     fread(&dir, sizeof(struct direct), 1, fp);
  580.     fread(&dir, sizeof(struct direct), 1, fp);
  581.     filename[DIRSIZ] = '\0';
  582.     for (;;) {
  583.         if (fread(&dir, sizeof(struct direct), 1, fp) <=0)
  584.             break;
  585.         if (dir.d_ino == 0)
  586.             continue;
  587.         strncpy(filename, dir.d_name, DIRSIZ);
  588.         vs_push(make_simple_string(filename));
  589.         vs_head = coerce_to_pathname(vs_head);
  590.         if ((name == Cnil || name == Kwild ||
  591.              equal(name, vs_head->pn.pn_name)) &&
  592.             (type == Cnil || type == Kwild ||
  593.              equal(type, vs_head->pn.pn_type))) {
  594.             vs_head->pn.pn_directory
  595.             = vs_base[0]->pn.pn_directory;
  596.             vs_head = truename(vs_head);
  597.         } else
  598.             vs_pop;
  599.     }
  600.     fclose(fp);
  601.     vs_push(Cnil);
  602.     while (vs_top > top + 1)
  603.         stack_cons();
  604.     vs_base = top;
  605. }
  606. #endif
  607.  
  608.  
  609. #ifdef DGUX
  610.  
  611.  
  612.  
  613.  
  614.  
  615.  
  616.  
  617.  
  618.  
  619.  
  620.  
  621.  
  622.  
  623.  
  624.  
  625.  
  626.  
  627.  
  628.  
  629.  
  630.  
  631.  
  632.  
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658. #endif
  659.  
  660. siLchdir()
  661. {
  662.     char filename[MAXPATHLEN];
  663.  
  664.     check_arg(1);
  665.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  666.     coerce_to_filename(vs_base[0], filename);
  667.     if (chdir(filename) < 0)
  668.         FEerror("Can't change the current directory to ~S.",
  669.             1, vs_base[0]);
  670. }
  671.  
  672. init_unixfsys()
  673. {
  674.     make_function("TRUENAME", Ltruename);
  675.     make_function("RENAME-FILE", Lrename_file);
  676.     make_function("DELETE-FILE", Ldelete_file);
  677.     make_function("PROBE-FILE", Lprobe_file);
  678.     make_function("FILE-WRITE-DATE", Lfile_write_date);
  679.     make_function("FILE-AUTHOR", Lfile_author);
  680.     make_function("USER-HOMEDIR-PATHNAME", Luser_homedir_pathname);
  681.     make_function("DIRECTORY", Ldirectory);
  682.  
  683.     make_si_function("CHDIR", siLchdir);
  684. }
  685.